package nancal.mp.mvc.dev


import nancal.mp.db.mongo.entity.dev.DbSetting
import nbcp.base.annotation.Require
import nbcp.base.annotation.mvc.OpenAction
import nbcp.base.comm.BatchReader
import nbcp.base.extend.AsString
import nbcp.base.extend.usingScope
import nbcp.myoql.db.db
import nbcp.myoql.db.mongo.MongoTemplateScope
import nbcp.myoql.db.mongo.base.MongoColumnName
import nbcp.myoql.db.mongo.query
import nbcp.myoql.db.mongo.updateById
import nbcp.myoql.db.sql.DataSourceScope
import org.springframework.boot.jdbc.DataSourceBuilder
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RequestMapping("/ops/ext")
@RestController
@OpenAction
class IamDbOpsController {

    data class FixDbSetting(
        var mongo: DbSetting = DbSetting(),
        var mysql: DbSetting = DbSetting(),


        @Require
        var oldAppIp: String = "",
        @Require
        var appIp: String = ""
    )

    @PostMapping("/fix-nancal-db-ip")
    fun changeAppIp(@RequestBody setting: FixDbSetting) {
        setIam(setting);
        setNancalEC(setting);
    }


    fun getDataSource(setting: DbSetting, db: String): DataSourceScope {

        DataSourceBuilder
            .create()
            .type(com.zaxxer.hikari.HikariDataSource::class.java)
            .url(setting.getMariadbUri(db))
            .username(setting.user)
            .password(setting.password)
            .build().apply {
                return DataSourceScope(this)
            }
    }

    private fun setNancalEC(setting: FixDbSetting) {
        if (setting.mysql.port <= 0) {
            return
        }

        usingScope(getDataSource(setting.mysql, "nancal_enterprise_container")) {
            db.sql.rawUpdate(
                "update ec_application_info \n" +
                        "set address = REPLACE(address, '${setting.oldAppIp}', '${setting.appIp}' ) \n" +
                        "where address like '%${setting.oldAppIp}%' "
            ).exec()


            db.sql.rawUpdate(
                "update ec_application_info \n" +
                        "set logo = REPLACE(logo, '${setting.oldAppIp}', '${setting.appIp}' ) \n" +
                        "where logo like '%${setting.oldAppIp}%' "
            ).exec()


            db.sql.rawUpdate(
                "update ec_application_version \n" +
                        "set actual_address = REPLACE(actual_address, '${setting.oldAppIp}', '${setting.appIp}' ) \n" +
                        "where actual_address like '%${setting.oldAppIp}%' "
            ).exec()
        }
    }

    private fun setIam(setting: FixDbSetting) {
        if (setting.mongo.port <= 0) {
            return
        }


        usingScope(MongoTemplateScope(db.mongo.getMongoTemplateByUri(setting.mongo.getMongoUri("iam"))!!)) {
            var reader = BatchReader.init(50, { skip, take ->
                db.mongo.dynamicEntity("tenantApplication").query()
                    .where { MongoColumnName("") mongoLike setting.oldAppIp }
                    .limit(skip, take)
                    .toList()
            });

            for (app in reader) {
                var url = app.get("url").AsString()
                if (url.isEmpty()) {
                    continue;
                }

                if (url.startsWith("http://${setting.appIp}", ignoreCase = true)) {
                    continue;
                }

                url = Regex("(http\\:\\/\\/)([^/]+)(.*)").replaceFirst(url, "$1${setting.appIp}$3")

                db.mongo.dynamicEntity("tenantApplication")
                    .updateById(app.get("id").AsString())
                    .set("url", url)
                    .exec()
            }
        }
    }
}
